package com.rongji.dfish.demo.editor.service;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.rongji.dfish.base.DfishException;
import com.rongji.dfish.base.Utils;
import com.rongji.dfish.demo.constant.DemoConstants;
import com.rongji.dfish.demo.editor.service.uiadaptor.ComponentData;
import com.rongji.dfish.demo.editor.view.EditorView;
import com.rongji.dfish.demo.entity.DfishView;
import com.rongji.dfish.demo.entity.DfishViewNode;
import com.rongji.dfish.framework.IdGenerator;
import com.rongji.dfish.framework.dao.PubCommonDAO;

@Service
public class EditorService extends CommonService<DfishViewNode> {
	// 编辑状态
	public static final String STATUS_EDIT = "0";
	// FIXME 定版的英文单词是?
	public static final String STATUS_VERSION = "1";
	// 跟节点
	
	@Autowired
	private PubCommonDAO pubCommonDAO;
	
	public PubCommonDAO getPubCommonDAO() {
		return pubCommonDAO;
	}

	public void setPubCommonDAO(PubCommonDAO pubCommonDAO) {
		this.pubCommonDAO = pubCommonDAO;
	}

	public List<DfishViewNode> findViewNodes(String viewId) {
		@SuppressWarnings("unchecked")
        List<DfishViewNode> result = (List<DfishViewNode>) pubCommonDAO.getQueryList(
				"FROM DfishViewNode t WHERE t.viewId=? ORDER BY t.nodeOrder ASC", viewId);
		if (result == null) {
			return Collections.emptyList();
		}
		return result;
	}
	public DfishViewNode getViewNode(String nodeId) {
		assert(nodeId!=null);
		if (DemoConstants.ID_ROOT.equals(nodeId)) {
			DfishViewNode rootNode = new DfishViewNode();
			rootNode.setNodeId(DemoConstants.ID_ROOT);
			rootNode.setNodeType("");
			return rootNode;
		}
		@SuppressWarnings("unchecked")
        List<DfishViewNode> result = (List<DfishViewNode>) pubCommonDAO.getQueryList(
				"FROM DfishViewNode t WHERE t.nodeId=?", nodeId);
		if(result.size()>0){
			return result.get(0);
		}
		return null;
	}
	/**
	 * 取得某个节点下最新的排序号。如果大约99999 则等于99999
	 * @param parentNode
	 * @return
	 */
	public Long getNewOrder(String nodeParent) {
		@SuppressWarnings("unchecked")
        List<Number> result = (List<Number>) pubCommonDAO.getQueryList(
				"SELECT MAX(t.nodeOrder) FROM DfishViewNode t WHERE t.nodeParent=? ", nodeParent);
		if(result==null||result.size()==0||result.get(0)==null){
			return 10L;
		}
		Long l=result.get(0).longValue();
		Long r=l+10;
		if(r<0){r=0L;}
		if(r>999999){r=999999L;}
		return r;
	}
	public void save(DfishViewNode viewNode) {
		pubCommonDAO.save(viewNode);
	}
	public void update(DfishViewNode viewNode) {
		pubCommonDAO.update(viewNode);
	}
	public List<DfishViewNode> findSubNodes(
			String nodeId) {
		@SuppressWarnings("unchecked")
        List<DfishViewNode> result = (List<DfishViewNode>) pubCommonDAO.getQueryList(
				"FROM DfishViewNode t WHERE t.nodeParent=?  ORDER BY t.nodeOrder ASC", nodeId);
		if (result == null) {
			return Collections.emptyList();
		}
		return result;
	}
	public List<DfishViewNode> findSubNodes(
			String nodeId,String viewId) {
		@SuppressWarnings("unchecked")
        List<DfishViewNode> result = (List<DfishViewNode>) pubCommonDAO.getQueryList(
				"FROM DfishViewNode t WHERE t.nodeParent=? AND t.viewId=? ORDER BY t.nodeOrder ASC", nodeId,viewId);
		if (result == null) {
			return Collections.emptyList();
		}
		return result;
	}
	
	public DfishViewNode getDfishViewNode(String nodeId){
		if(Utils.isEmpty(nodeId)){
			return null;
		}
		return (DfishViewNode) pubCommonDAO.queryAsAnObject("FROM DfishViewNode t WHERE t.nodeId=?", nodeId);
	}
	
	public List<DfishViewNode> findAllSubNodes(String nodeId,String viewId){
		List<DfishViewNode> result = new ArrayList<DfishViewNode>();
		List<String> subNodeId = new ArrayList<String>();
		List<DfishViewNode> subNodes ;
		subNodeId.add(nodeId);
		while(subNodeId.size()!=0){
			List<String> readyRemoveId = new ArrayList<String>();
			int size = subNodeId.size();
			subNodes = null;
			for(int i = 0; i < size; i++){
				String id = subNodeId.get(i);
				readyRemoveId.add(id);
				subNodes = (List<DfishViewNode>) pubCommonDAO.getQueryList(
						"FROM DfishViewNode t WHERE t.nodeParent=? AND t.viewId=? ORDER BY t.nodeOrder ASC", id,viewId);
				
//				DfishViewNode parent = getDfishViewNode(id);
				if(subNodes.size() != 0){
					result.addAll(subNodes);
					for(DfishViewNode node: subNodes){
						subNodeId.add(node.getNodeId());
					}
				}
			}
			
			subNodeId.removeAll(readyRemoveId);
			readyRemoveId.removeAll(readyRemoveId);
//			int size2 = readyRemoveId.size();
//			for(int i = 0; i<size2; i++){
//				readyRemoveId.remove(i);
//			}
			
		}
		
		return result;
		
	}
	
//	public Map<String,List<DfishViewNode>> findAllSubNodes(String nodeId,String viewId){
//		Map<String,List<DfishViewNode>> result = new HashMap<String,List<DfishViewNode>>();
//		List<String> subNodeId = new ArrayList<String>();
//		List<DfishViewNode> subNodes ;
//		subNodeId.add(nodeId);
//		while(subNodeId.size()!=0){
//			List<String> readyRemoveId = new ArrayList<String>();
//			int size = subNodeId.size();
//			subNodes = null;
//			for(int i = 0; i < size; i++){
//				String id = subNodeId.get(i);
//				System.out.println("ID="+id);
//				readyRemoveId.add(id);
//				subNodes = (List<DfishViewNode>) pubCommonDAO.getQueryList(
//						"FROM DfishViewNode t WHERE t.nodeParent=? AND t.viewId=? ORDER BY t.nodeOrder ASC", id,viewId);
//				
//				DfishViewNode parent = getDfishViewNode(id,viewId);
//				if(subNodes.size() != 0){
//					result.put(parent.getNodeId(), subNodes);
//					for(DfishViewNode node: subNodes){
//						subNodeId.add(node.getNodeId());
//					}
//				} else {
//					result.put(parent.getNodeId(), null);
//					
//				}
//			}
//			
//			subNodeId.removeAll(readyRemoveId);
//			readyRemoveId.removeAll(readyRemoveId);
////			int size2 = readyRemoveId.size();
////			for(int i = 0; i<size2; i++){
////				readyRemoveId.remove(i);
////			}
//			
//		}
//		
//		return result;
//	}
	
	public List<DfishViewNode> findTopNodes(String viewId) {
		@SuppressWarnings("unchecked")
        List<DfishViewNode> result = (List<DfishViewNode>) pubCommonDAO.getQueryList(
				"FROM DfishViewNode t WHERE t.viewId=? AND t.nodeParent=? ORDER BY t.nodeOrder ASC", viewId, DemoConstants.ID_ROOT);
		if (result == null) {
			return Collections.emptyList();
		}
		return result;
	}
	public void delete(DfishViewNode viewNode) {
		if(viewNode!=null){
			pubCommonDAO.delete(viewNode);
		}
	}
	public DfishViewNode deleteNodesCascade(String rootNodeId) {
		DfishViewNode viewNode =getViewNode(rootNodeId);
		String viewId=viewNode.getViewId();
		List<DfishViewNode> viewNodes=findViewNodes(viewId);
		TreeMap<String,DfishViewNode> toDelete=new TreeMap<String,DfishViewNode>();
		toDelete.put(rootNodeId, getViewNode(rootNodeId));
		findSubViewNodes(rootNodeId,viewNodes,toDelete);
		pubCommonDAO.getHibernateTemplate().deleteAll(toDelete.values());
		return viewNode;
	}
	private void findSubViewNodes(String nodeId,
			List<DfishViewNode> viewNodes,
			TreeMap<String, DfishViewNode> toDelete) {
		for(DfishViewNode n:viewNodes){
			if(n.getNodeParent().equals(nodeId)){
				if(toDelete.containsKey(n.getNodeId())){//防止错误数据，比如父ID还是自己而造成死循环
					continue;
				}
				toDelete.put(n.getNodeId(), n);
				findSubViewNodes(n.getNodeId(),viewNodes,toDelete);
			}
		}
	}
	public DfishView getView(String viewId) {
		DfishView result = (DfishView) pubCommonDAO.queryAsAnObject("FROM DfishView t WHERE t.viewId=?", viewId);
		return result;
	}
//	 @SuppressWarnings("unchecked")
//    public List<DfishViewDir> findViewDirs4Path(String dirId) {
//    	if (Utils.isEmpty(dirId)) {
//    		return Collections.emptyList();
//    	}
//    	
//        DfishViewDir currDir = (DfishViewDir) pubCommonDAO.queryAsAnObject("FROM DfishViewDir t WHERE t.dirId=?", dirId);
//        List<DfishViewDir> dirs = null;
//        Set<String> mainPath = new HashSet<String>();
//        if (currDir != null) {
//        	String dirPath = currDir.getDirPath();
//        	for (String dir : dirPath.split("/")) {
//        		if (Utils.notEmpty(dir)) {
//        			mainPath.add(dir);
//        		}
//        	}
////        	String rootId = currDir.getDirRoot();
//        	dirs = (List<DfishViewDir>) pubCommonDAO.getQueryList("FROM DfishViewDir t WHERE t.dirParent=? ORDER BY t.dirParent,t.dirOrder", new Object[]{ DemoConstants.ID_ROOT });
//        } else {
//        	dirs = (List<DfishViewDir>) pubCommonDAO.getQueryList("FROM DfishViewDir t WHERE t.dirParent=? ORDER BY t.dirParent,t.dirOrder", new Object[]{ DemoConstants.ID_ROOT });
//        }
//    	if (Utils.isEmpty(dirs)) {
//    		return Collections.emptyList();
//    	}
//    	
//	    return dirs;
//    }
	public String sortNode(String nodeId, String moveType) throws DfishException {
		//找到同级的节点
		DfishViewNode theNode= (DfishViewNode) pubCommonDAO.queryAsAnObject("FROM DfishViewNode t WHERE t.nodeId=?", nodeId);
		@SuppressWarnings("unchecked")
        List<DfishViewNode> nodeList = (List<DfishViewNode>) pubCommonDAO.getQueryList(
					"FROM DfishViewNode t " +
					"WHERE t.nodeParent=? AND t.viewId=? " +
					"ORDER BY t.nodeOrder,t.nodeId",
					theNode.getNodeParent(),theNode.getViewId());
		int index=-1;
		for(int i=0;i<nodeList.size();i++){
			if(nodeList.get(i).getNodeId().equals(nodeId)){
				index=i;
				break;
			}
		}
		if(index==-1){
			return "指定的代码不存在或者已经删除";
//			throw new DfishException("指定的代码不存在或者已经删除","DFISH-00000");
		}else if(index==0&&(DemoConstants.MOVE_UP.equals(moveType)||DemoConstants.MOVE_TOP.equals(moveType))){
			return "已经是最顶部,不能继续上移";
//			throw new DfishException("已经是最顶部,不能继续上移","DFISH-00000");
		}else if(index==nodeList.size()-1&&(DemoConstants.MOVE_DOWN.equals(moveType)||DemoConstants.MOVE_BOTTOM.equals(moveType))){
			return "已经在最底部,不能继续下移";
//			throw new DfishException("已经在最底部,不能继续下移","DFISH-00000");
		}
		if(DemoConstants.MOVE_UP.equals(moveType)){
			DfishViewNode temp=nodeList.get(index);
			nodeList.set(index, nodeList.get(index-1));
			nodeList.set(index-1, temp);
		}else if(DemoConstants.MOVE_DOWN.equals(moveType)){
			DfishViewNode temp=nodeList.get(index);
			nodeList.set(index, nodeList.get(index+1));
			nodeList.set(index+1, temp);
		}else if(DemoConstants.MOVE_TOP.equals(moveType)){
			DfishViewNode temp=nodeList.remove(index);
			nodeList.add(0, temp);
		}else if(DemoConstants.MOVE_BOTTOM.equals(moveType)){
			DfishViewNode temp=nodeList.remove(index);
			nodeList.add(temp);
		}
		for(int i=0;i<nodeList.size();i++){
			DfishViewNode code=nodeList.get(i);
			if(code.getNodeOrder()==null||
					code.getNodeOrder().intValue()!=10*(i+1)){
				code.setNodeOrder(10L*(i+1));
				pubCommonDAO.update(code);
			}
		}
		return "";
	}
	public void moveNode(String nodeId, String pNode) {
//		PubCommonDAO dao=FrameworkHelper.getDAO();
		//找到同级的节点
		//FIXME 不能移动到自己或自己下级的节点中去
		//FIXME 上下级节点必须兼容才能移入
		Number maxNo=null;
		DfishViewNode theNode = (DfishViewNode) pubCommonDAO.queryAsAnObject(
				"FROM DfishViewNode t WHERE t.nodeId=?", nodeId);
		if(DemoConstants.ID_ROOT.equals(pNode)){
			maxNo=(Number) pubCommonDAO.queryAsAnObject(
					"SELECT MAX(t.nodeOrder) FROM DfishViewNode t WHERE t.nodeParent=? AND viewId=?", pNode,theNode.getViewId());
		}else{
			maxNo=(Number) pubCommonDAO.queryAsAnObject(
					"SELECT MAX(t.nodeOrder) FROM DfishViewNode t WHERE t.nodeParent=?", pNode);
		}
		if(maxNo==null){
			maxNo=10;
		}
		Long newOrder=maxNo.intValue()+10L; 
		if(newOrder>999999L){
			newOrder=999999L;
		}
		
		theNode.setNodeParent(pNode);
		theNode.setNodeOrder(newOrder);
		pubCommonDAO.update(theNode);
		
//		List<DfishViewNode> nodeList = (List<DfishViewNode>) dao.getQueryList(
//				"FROM DfishViewNode t " +
//				"WHERE t.nodeParent=? AND t.viewId=? " +
//				"ORDER BY t.nodeOrder,t.nodeId",
//				theNode.getNodeParent(),theNode.getViewId());
		
	}

	/**
	 * 重构视图
	 * @param viewId
	 * @param data
	 */
	public void rebuild(final String viewId, ComponentData data) {
		if (Utils.isEmpty(viewId) || data == null) {
			return;
		}
		// FIXME 对于重构后的视图校验该如何进行?
		final List<DfishViewNode> nodes = new ArrayList<DfishViewNode>();
		Map<String, Long> orderMap = new HashMap<String, Long>();
		DfishViewNode pNode = new DfishViewNode();
		pNode.setNodeId(DemoConstants.ID_ROOT);
		pNode.setViewId(viewId);
		List<ComponentData> subData = data.getNodes();
		DfishViewNode root = parseViewNode(pNode, data, orderMap);
		nodes.add(root);
		fillNodes(nodes, root, subData, orderMap);
		pubCommonDAO.getHibernateTemplate().execute(new HibernateCallback<Object>() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
	            Query delete = session.createQuery("DELETE FROM DfishViewNode t WHERE t.viewId=?").setString(0, viewId);
	            delete.executeUpdate();
	            for (DfishViewNode viewNode : nodes) {
	            	session.save(viewNode);
	            }
	            return null;
            }
		});
	}
	
	private void fillNodes(List<DfishViewNode> nodes, DfishViewNode pNode, List<ComponentData> subData, Map<String, Long> orderMap) {
		if (Utils.notEmpty(subData)) {
			for (ComponentData item : subData) {
				List<ComponentData> subItem = item.getNodes();
				DfishViewNode node = parseViewNode(pNode, item, orderMap);
				nodes.add(node);
				fillNodes(nodes, node, subItem, orderMap);
			}
		}
	}
	
	private DfishViewNode parseViewNode(DfishViewNode pNode, ComponentData data, Map<String, Long> orderMap) {
		DfishViewNode viewNode = new DfishViewNode();
		viewNode.setNodeId(CommonService.getNewId());
		viewNode.setNodeName(getNodeName(data));
		String nodeParent = pNode.getNodeId();
		viewNode.setNodeParent(nodeParent);
		viewNode.setNodeType(data.getType());
		viewNode.setViewId(pNode.getViewId());
		Long nodeOrder = orderMap.get(nodeParent);
		if (nodeOrder == null) {
			nodeOrder = 10L;
		} else {
			nodeOrder += 10L;
		}
		orderMap.put(nodeParent, nodeOrder);
		
		viewNode.setNodeOrder(nodeOrder);
		
		// 将子节点清空,不在内容字段中显示
		data.setNodes(null);
		String nodeContent = new Gson().toJson(data);
		viewNode.setNodeContent(nodeContent);
		return viewNode;
	}
	
	public static String getNodeName(ComponentData data) {
		if (data == null) {
			return "";
		}
		String nodeName = null;
		Map<String, String> props = data.getProps();
		if (props != null) {
			nodeName = props.get("id");
			if (Utils.isEmpty(nodeName)) {
				nodeName = props.get("name");
				if (Utils.notEmpty(nodeName)) {
					nodeName = "*" + nodeName;
				}
			}
			//没有name的话，不能去text，如果text内容很多，保存的时候会报错。如Html
//			if (Utils.isEmpty(nodeName)) {
//				nodeName = props.get("text");
//				if (Utils.notEmpty(nodeName)) {
//					nodeName = "*" + nodeName;
//				}
//			}
		}
		if (nodeName == null) {
			nodeName = "";
		}
		return nodeName;
	}
	
	
	/**
	 * 保存时判断与上一版本是否重复
	 * 如是，返回false;如否，返回true
	 * @param dView
	 * @return
	 */
	public boolean judgeSaveVersion(DfishView dView){
		
		List<Long> Version = (List<Long>) pubCommonDAO.getQueryList("SELECT t.viewVersion FROM DfishView t WHERE t.viewOrigin=? order by t.viewVersion desc", dView.getViewOrigin());
		if(Version.get(0)==1){
			return true;
		}
		String secondVersiondViewId = (String) pubCommonDAO.queryAsAnObject("SELECT t.viewId FROM DfishView t WHERE t.viewVersion=? AND t.viewOrigin=?",  new Object[]{ Version.get(1), dView.getViewOrigin() });
		String maxVersiondViewId = (String) pubCommonDAO.queryAsAnObject("SELECT t.viewId FROM DfishView t WHERE t.viewVersion=? AND t.viewOrigin=?",  new Object[]{ Version.get(0), dView.getViewOrigin() });

		List<DfishViewNode> maxVersionNodes = (List<DfishViewNode>) pubCommonDAO.getQueryList("FROM DfishViewNode t WHERE t.viewId=? ORDER BY t.nodeOrder ASC", new Object[]{ maxVersiondViewId });
		List<DfishViewNode> secondVersionNodes = (List<DfishViewNode>) pubCommonDAO.getQueryList("FROM DfishViewNode t WHERE t.viewId=? ORDER BY t.nodeOrder ASC", new Object[]{ secondVersiondViewId });
		
		ComponentData maxData = EditorView.getComponentData(maxVersionNodes);
		ComponentData secondData = EditorView.getComponentData(secondVersionNodes);
		String json1 = null;
		String json2 = null;
		
		if (maxData != null) {
			json1 = new Gson().toJson(maxData);
		}
		if (secondData != null) {
			json2 = new Gson().toJson(secondData);
		}
		return !(json1.equals(json2));
		
	}
	
	/**
	 * 保存版本并返回新版本的视图编号
	 * 若跟上一版本重复，则不保存
	 * @param viewId
	 * @return
	 */
	public boolean saveVersion(String viewId,String viewCreator, String viewRemark) {
		if (Utils.isEmpty(viewId)) {
			return false;		
		}
		final DfishView dView = getView(viewId);
		if(judgeSaveVersion(dView)){
			if (dView.getViewVersion() == null) {
	    		dView.setViewVersion(1L);
	    	}
	    	final DfishView newView = new DfishView();
			Utils.copyPropertiesExact(newView, dView);//FIXME 理论上应该是指定的
			
			newView.setViewCreator(viewCreator);
			newView.setViewRemark(viewRemark);
			
			Date now = new Date(System.currentTimeMillis());
			newView.setViewId(CommonService.getNewId());
			newView.setUpdateTime(now);
			newView.setCreateTime(now);
			newView.setViewStatus(STATUS_VERSION);
			pubCommonDAO.save(newView);
			dView.setUpdateTime(now);
			dView.setViewVersion(dView.getViewVersion() + 1L);
			pubCommonDAO.update(dView);
			
			copyNodes(viewId, newView.getViewId(), false);
			return true;
		} else {
			return false;
		}

	}
	
	public List<DfishView> findVersionViews(String viewOrigin, String viewStatus) {
		@SuppressWarnings("unchecked")
        List<DfishView> result = (List<DfishView>) pubCommonDAO.getQueryList("FROM DfishView t WHERE t.viewOrigin=? AND t.viewStatus=? ORDER BY t.viewVersion DESC", new Object[]{ viewOrigin, viewStatus });
		if (result == null) {
			return Collections.emptyList();
		}
		return result;
	}
	
	public List<String> findPathDirNames(String dirId) {
		if (Utils.isEmpty(dirId)) {
			return Collections.emptyList();
		}
		String dirPath = (String) pubCommonDAO.queryAsAnObject("SELECT t.dirPath FROM DfishViewDir t WHERE t.dirId=?", dirId);
		List<String> result = null;
		if (Utils.notEmpty(dirPath)) {
			final String[] pathArray = dirPath.split("/");
			result = pubCommonDAO.getHibernateTemplate().execute(new HibernateCallback<List<String>>() {
                public List<String> doInHibernate(Session session) throws HibernateException, SQLException {
                	Query query = session.createQuery("SELECT t.dirName FROM DfishViewDir t WHERE t.dirId=?");
                	List<String> result = new ArrayList<String>();
                	for (String dirId : pathArray) {
                		if (Utils.isEmpty(dirId)) {
                			continue;
                		}
                		query.setString(0, dirId);
                		String dirName = (String) query.uniqueResult();
                		result.add(dirName);
                	}
	                return result;
                }
			});
		}
		if (result == null) {
			return Collections.emptyList();
		}
		return result;
	}
	
	
	/**
	 * 复制节点并保存
	 * @param OldId
	 * @param newNodeViewId  是否清除节点
	 */
	public void copyNodes(String oldId, final String newViewId, final boolean clearBeforeCopy){
		
		final List<DfishViewNode> data = (List<DfishViewNode>) pubCommonDAO.getQueryList("FROM DfishViewNode t WHERE t.viewId=?", new Object[]{ oldId });
    	final List<DfishViewNode> newViewNodes=new ArrayList<DfishViewNode>(data.size());
    	final Map<String,String> nodeIdMap=new HashMap<String,String>();
    	
    	for (DfishViewNode viewNode : data) {
    		DfishViewNode newNode=new DfishViewNode();
    		Utils.copyPropertiesExact(newNode, viewNode);
    		newNode.setNodeId(CommonService.getNewId());
    		newNode.setViewId(newViewId);
    		newViewNodes.add(newNode);
    		nodeIdMap.put(viewNode.getNodeId(), newNode.getNodeId());
		}
		
    	pubCommonDAO.getHibernateTemplate().execute(new HibernateCallback<Object>() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
            	
            	if(clearBeforeCopy){
            		
            		List<DfishViewNode> viewNodes2del = session.createQuery("FROM DfishViewNode t WHERE t.viewId=?").setString(0, newViewId).list();
            		for(DfishViewNode viewNode : viewNodes2del){
                		session.delete(viewNode);
                	}
            	}
            	
    			for(DfishViewNode newNode : newViewNodes){
            		String newParent=nodeIdMap.get(newNode.getNodeParent());
            		if(newParent!=null){
            			newNode.setNodeParent(newParent);
            		}
            		session.save(newNode);
            	}
    			
                return null;
            }
		});
    	
	}
	
	public boolean doPaste(DfishViewNode parent, DfishViewNode sub){
		List<DfishViewNode> copyNodes = new ArrayList<DfishViewNode>();
		copyNodes = findAllSubNodes(sub.getNodeId(),sub.getViewId());
		copyNodes.add(0,sub);
		
		if(copyNodes.size()==0){
			return false;
		} else if(copyNodes.size()==1){
			DfishViewNode node = new DfishViewNode();
			node = sub;
			node.setNodeName(sub.getNodeName());
			node.setNodeId(CommonService.getNewId());
			node.setNodeParent(parent.getNodeId());
			node.setViewId(parent.getViewId());
			node.setNodeOrder(getNewOrder(node.getNodeParent()));
			save(node);
			return true;
		} else {
			//先将最大的父节点保存
			DfishViewNode node = new DfishViewNode();
			node.setNodeId(CommonService.getNewId());
			node.setNodeParent(parent.getNodeId());
			node.setViewId(parent.getViewId());
			node.setNodeName("copy_"+sub.getNodeName());
			node.setNodeType(sub.getNodeType());
			node.setNodeContent(sub.getNodeContent());
			node.setNodeOrder(getNewOrder(node.getNodeParent()));
			save(node);
			
			final Map<String,String> nodeIdMap=new HashMap<String,String>();
			final List<DfishViewNode> newViewNodes=new ArrayList<DfishViewNode>(copyNodes.size());
			nodeIdMap.put(sub.getNodeId(), node.getNodeId());
			
			for (DfishViewNode viewNode : copyNodes) {
				if(!viewNode.getNodeId().equals(sub.getNodeId())){
					DfishViewNode newNode=new DfishViewNode();
					Utils.copyPropertiesExact(newNode, viewNode);
					newNode.setNodeId(CommonService.getNewId());
					newNode.setViewId(parent.getViewId());
					newViewNodes.add(newNode);
					nodeIdMap.put(viewNode.getNodeId(), newNode.getNodeId());
				} else{
					newViewNodes.add(node);
				}
			}
			for(DfishViewNode newNode : newViewNodes){
				if(!newNode.getNodeId().equals(node.getNodeId())){
					String newParent=nodeIdMap.get(newNode.getNodeParent());
	        		if(newParent!=null){
	        			newNode.setNodeParent(newParent);
	        		}
	        		save(newNode);
				}
				
        	}
			
			return true;
		}
	}
	
	public String recoveryVersion(String viewId) {
		if (Utils.isEmpty(viewId)) {
			return null;
		}
		final DfishView dView = getView(viewId);
		copyNodes(viewId, dView.getViewOrigin(), true);
		
		final List<DfishViewNode> viewNodes = findViewNodes(viewId);
		final List<DfishViewNode> viewNodes2del = findViewNodes(dView.getViewOrigin());
		
		return (String) pubCommonDAO.getHibernateTemplate().execute(new HibernateCallback<Object>() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
            	//删除正在编辑的视图节点
            	for(DfishViewNode viewNode : viewNodes2del){
            		session.delete(viewNode);
            	}
            	List<DfishViewNode> newViewNodes= new ArrayList<DfishViewNode>(viewNodes.size());
            	Map<String,String>nodeIdMap=new HashMap<String,String>();
            	//拷贝想恢复的试图节点到新的视图节点上
            	for (DfishViewNode viewNode : viewNodes){
            		DfishViewNode newNode = new DfishViewNode();
            		Utils.copyPropertiesExact(newNode, viewNode);
            		newNode.setNodeId(IdGenerator.getSortedId());
            		newNode.setViewId(dView.getViewOrigin());
            		newViewNodes.add(newNode);
            		nodeIdMap.put(viewNode.getNodeId(),newNode.getNodeId());
            	    }
            	//判断是否有父类视图节点进行保存新的视图节点
            	for(DfishViewNode newNode : newViewNodes){
            		String newParent=nodeIdMap.get(newNode.getNodeParent());
            		if(newParent!=null){
            			newNode.setNodeParent(newParent);
            		}
            		session.save(newNode);
            	}
            		return dView.getViewOrigin();
            }

		});
				
	}
	
}

